/*********************************************************************************
 *      Copyright:  (C) 2021 maqianjun<1253008684@qq.com>
 *                  All rights reserved.
 *
 *       Filename:  mqtt_pub.c
 *    Description:  This file for connect broker to publish missage
 *                 
 *        Version:  1.0.0(28/07/21)
 *         Author:  maqianjun <1253008684@qq.com>
 *      ChangeLog:  1, Release initial version on "28/07/21 11:08:34"
 *                 
 ********************************************************************************/
#include<stdio.h>
#include<mosquitto.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<iniparser.h>
#include<dictionary.h>

#include"cJSON.h"

typedef struct mosq_ctx_s
{
    char             serverip[64];
    int              port;

    char             id[64];
    char             username[64];

    char             password[64];
    char             topic[64];
    char             pub_id[64];
    char             version[64];
    char             method[64];
    char             json_id[64];

    int              pub_qos;
    int              interval;

}mosq_ctx_t;

int get_iniparser_data(const  char *conf_file, mosq_ctx_t  *mqtt);
void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc);

int main(int argc, char *argv[])
{
    bool                session=true;
    const   char       *conf_file = "./conf_file.ini";

    mosq_ctx_t          mqtt;
    struct  mosquitto  *mosq;
    
    char            *serverip = NULL;
    int                 port;
    char            *topic = NULL;
    char            *username = NULL;
    char            *password = NULL;
    char            *id = NULL;

    get_iniparser_data(conf_file, &mqtt);
    
    mosquitto_lib_init();//使用mosquitto库之前需要初始化；
    
    mosq = mosquitto_new(mqtt.id, session, (void *)&mqtt);//创建一个新的客户端，在这里我们是pubilsh；
    if (!mosq)
    {
        printf ("error mosquitto_new()\n");
        goto cleanUp;

    }
    mosquitto_connect_callback_set(mosq, pub_conn_callback);

    if (MOSQ_ERR_SUCCESS != mosquitto_username_pw_set(mosq, mqtt.username, mqtt.password))//配置用户名和密码；
    {
        printf ("error mosquitto_isername_pw_set()\n");
        goto cleanUp;
        
    }
    while (1)
    {   
        if (MOSQ_ERR_SUCCESS != mosquitto_connect(mosq, mqtt.serverip, mqtt.port, mqtt.interval))
        {
            printf ("mosquitto_connect()\n");
            continue;
            goto cleanUp;

        }
        printf ("connected\n");
        mosquitto_loop_forever(mosq,-1,1);//无线阻塞循环调用loop；

        sleep(5);
    }   
cleanUp:
    
    printf("program will exit\n");
    mosquitto_disconnect(mosq);//断开与broker之间的连接；
    mosquitto_destroy(mosq);//在我们用完这个client之后就需要把他free掉；

    return 0;
}
//void *obj  *mosq 指针中的有一个变量也指向OBJ;
void pub_conn_callback(struct mosquitto *mosq, void *obj, int rc)//rc : 0表示成功，
{ 
            
        mosq_ctx_t      *mqtt;
    
        int               mid;
        char             *msg = NULL;
        bool              retain = true;
        int                pub_qos;
        float             temperature = 12.53008684;
        
        
        if( rc != 0 || !obj)
        {

            printf ("connect error in pub_conn_callback\n");
            mosquitto_disconnect(mosq);
            mosquitto_destroy(mosq);
        }
        
        mqtt = (mosq_ctx_t *)obj;
        

        cJSON *data_root = cJSON_CreateObject();
        cJSON_AddNumberToObject(data_root, "CurrentTemperature_9",temperature);
   
        cJSON *root = cJSON_CreateObject();
    
        cJSON_AddItemToObject(root, "method",cJSON_CreateString(mqtt->method));
        cJSON_AddItemToObject(root, "id",cJSON_CreateString(mqtt->pub_id));
        cJSON_AddItemToObject(root, "params",data_root);
        cJSON_AddItemToObject(root, "version",cJSON_CreateString(mqtt->version));

        msg = cJSON_Print(root);
        
        cJSON_Delete(root);

        printf ("msg=%s\n",msg);
      
        if(MOSQ_ERR_SUCCESS == mosquitto_publish(mosq, &mid, mqtt->topic, strlen(msg), msg, pub_qos, retain));
        {
            
            printf ("mosquitto_publish successfully!!!\n");

        }
        free(msg);
        mosquitto_disconnect(mosq);
}


int get_iniparser_data(const  char *conf_file, mosq_ctx_t  *mqtt)
{

    dictionary      *dic = NULL;

    const    char                   *serverip = NULL;
             int                    serverport;

    const    char                   *id = NULL;
    const    char                   *username = NULL;

    const    char                   *password = NULL;
    const    char                   *topic = NULL;

    const    char                   *pub_id =NULL;

    const    char                   *version = NULL;
    const    char                   *method = NULL;
    const    char                   *json_id = NULL;
    int                             pub_qos;
    int                             interval;
    int                             qos;

    dic = iniparser_load( conf_file );
    if (dic == NULL)
    {

        printf ("error\n");

        return -1;
    }   

    serverip = iniparser_getstring( dic,"broker_address:serverip", "NULL" );
    strncpy(mqtt->serverip, serverip, sizeof(mqtt->serverip));
    

    printf ("$$$$$$\n");
    printf ("serverip:%s\n",mqtt->serverip);

    serverport=iniparser_getint( dic, "broker_address:port", -1);
    mqtt->port = serverport;
    printf ("serverport:%d\n",mqtt->port);

    id=iniparser_getstring( dic,"client_id:id", "NULL" );
    strncpy(mqtt->id, id, sizeof(mqtt->id));
    printf ("client_id : %s\n",mqtt->id);

    username=iniparser_getstring( dic, "username_password:username", "NULL" );
    strncpy(mqtt->username, username, sizeof(mqtt->username));
    printf ("username:%s\n", mqtt->username);

    password=iniparser_getstring( dic, "username_password:password", "NULL" );
    strncpy(mqtt->password, password, sizeof(mqtt->password));
    printf ("password:%s\n",mqtt->password);

    topic=iniparser_getstring( dic, "pub_topic:topic", "NULL");
    strncpy(mqtt->topic, topic, sizeof(mqtt->topic));
    printf ("topic:%s\n", mqtt->topic);

    pub_id=iniparser_getstring( dic, "json_style:id" , "NULL" );
    strncpy(mqtt->pub_id, pub_id, sizeof(mqtt->pub_id)); 
    printf ("pub_id= %s\n",mqtt->pub_id);

    version=iniparser_getstring( dic, "json_style:version", "NULL" );
    strncpy(mqtt->version, version, sizeof(mqtt->version));
    printf ("vwesion:%s\n",mqtt->version);

    method=iniparser_getstring( dic, "json_style:method", "NULL" );
    strncpy(mqtt->method, method, sizeof(mqtt->method));
    printf ("method: %s\n",mqtt->method);

    pub_qos=iniparser_getint( dic, "pub_qos:qos", 0);
    mqtt->pub_qos =pub_qos;
    printf ("%d\n",mqtt->pub_qos);

    interval=iniparser_getint( dic, "keep_alive:interval", 0);
    mqtt->interval=interval;
    printf ("%d\n",mqtt->interval);

    iniparser_freedict(dic);

    return 0 ;
}   














